package com.hotel.search.lucene;

import com.hotel.comm.bean.PageConfig;
import com.hotel.comm.bean.lucene.IndexableBean;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author XuSemon
 * @date 2015-4-14
 */
public class LuceneSearch {
    /**
     *
     */
    private DirectoryReader reader = null;
    /**
     *
     */
    private Directory directory = null;
    /**
     *
     */
    private IndexSearcher searcher;

    public LuceneSearch() {
    }

    /**
     * 构造函数
     *
     * @param fsPath
     * @param searchSize
     */
    public LuceneSearch(String fsPath) {
        try {
            directory = FSDirectory.open(new File(fsPath));
            reader = DirectoryReader.open(directory);
        } catch (IOException e) {
            e.printStackTrace();
        }
        searcher = new IndexSearcher(reader);
    }

    /**
     * 查询
     *
     * @param condition 查询条件
     * @param clazz     查询后返回的类类型
     * @return
     */
    @SuppressWarnings("rawtypes")
    public PageConfig<IndexableBean> search(LuceneSearchCondition condition, Class clazz) {
        List<IndexableBean> ibs = new ArrayList<IndexableBean>();
        try {
//			TopFieldCollector tc = TopFieldCollector.create(condition.getSort(), condition.getCurrentPage() * condition.getPageSize(), 
//					false, false, false, false);
//			searcher.search(condition.getQuery(), tc);
//			ScoreDoc[] hits = null;
//			int totalSize = tc.getTotalHits();
//			if(totalSize == condition.getCurrentPage() * condition.getPageSize()){
//				hits = topDocs.topDocs((condition.getCurrentPage() - 1) * condition.getPageSize(), condition.getCurrentPage() * condition.getPageSize()).scoreDocs;
//			}else {
//				hits = tc.topDocs((condition.getCurrentPage() - 1) * condition.getPageSize(), totalSize).scoreDocs;
//			}
            TopDocs topDocs = searcher.search(condition.getQuery(), condition.getCurrentPage() * condition.getPageSize(), condition.getSort());
            ScoreDoc[] hits = topDocs.scoreDocs;
            if (hits != null && hits.length > 0) {
                //查询起始记录位置
                int begin = (condition.getCurrentPage() - 1) * condition.getPageSize();
                //查询终止记录位置
                int end = Math.min(begin + condition.getPageSize(), hits.length);
                IndexableBean ib = (IndexableBean) clazz.newInstance();
                for (int i = begin; i < end; i++) {
//				for (ScoreDoc sd : hits) {
                    ScoreDoc sd = hits[i];
                    Document doc = searcher.doc(sd.doc);
                    ibs.add(ib.parse(doc));
                }
            }
            return new PageConfig<IndexableBean>(condition.getPageSize(), condition.getCurrentPage(), ibs, hits.length);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public void close() {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            ;
        }
    }
}
